package lambda;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.IntStream;

/**
 * java8新特性lambda新特性示例
 * lambda主要是对匿名内部类的实现写法的简化，核心思想：能推导出来的就尽量不写，省略函数接口名和方法名
 * 可选类型声明：不需要声明参数类型，编译器可以统一识别参数值
 * 可选的参数圆括号：一个参数无需定义圆括号，但多个参数需要定义圆括号
 * 可选的大括号：如果主体包含了一个语句，就不需要使用大括号
 * 可选的返回关键字：如果主体只有一个表达式返回值则编译器会自动返回值，大括号需要指定明表达式返回了一个数值
 *
 * @author <a href="mailto:sjj@jianzhimao.com">mojo</a>
 * copyright (C), 2013-2022, 广州九尾信息科技有限公司
 * @date 2022/3/18 17:31
 */
public class Lambda1 {
    public static void main(String[] args) {
        //1.方法引用
        List<Object> list = new ArrayList<>();
        list.add(1);
        list.forEach(System.out::println);
        list.forEach(n -> System.out.println(n + ""));
        //2.stream&parallelStream
        long start = System.nanoTime();
        int[] ints1 = IntStream.range(0, 10_000_000).filter(n -> n % 2 == 0).toArray();
        long end1 = System.nanoTime();
        long start1 = System.nanoTime();
        int[] ints2 = IntStream.range(0, 10_000_000).parallel().filter(n -> n % 2 == 0).toArray();
        long end2 = System.nanoTime();
        System.out.println(end1 - start);
        System.out.println(end2 - start1);
        //3.() -> {} 替代匿名内部类
        new Thread(() -> System.out.println(Thread.currentThread().getName())).start();
        //Collections.sort
        List<User> users = new ArrayList<>();
        users.add(new User("mojo"));
        users.add(new User("jj"));
        users.sort(Comparator.comparing(User::getName));
        //函数式接口
        FunctionInterfaceDemo demo = () -> System.out.println("工作");
        demo.work();
        //内置函数式接口示例Consumer,Supplier,Function,Predicate
        //Consumer，传入一个值处理
        Consumer<User> consumer = u -> System.out.println(u.getName());
        consumer.accept(new User("有参无返回值"));
        //Supplier，返回一个值
        Supplier<User> supplier = () -> new User("无参有返回值");
        User user = supplier.get();
        //Predicate，判断
        Predicate<User> pre = s -> user.getName().length() > 0;
        System.out.println(pre.test(user));
        //Function,传入一个值处理后返回一个值
        Function<User, String> function = u -> u.getName() + u.getClass();
        String s = function.apply(new User("lambda实现Function接口"));
        System.out.println("function>>>" + s);
        User user1 = users.stream().parallel().max(Comparator.comparing(User::getName)).orElse(new User());
        System.out.println(user1);
        List<Integer> primes = Arrays.asList(2, 3, 5, 7);
        final int factor = 2;
        //lambda只能引用final变量
        primes.forEach(element -> System.out.println(factor));

        //lambda省略规则

    }
}
